﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SD.Commons.DataFilters;
// ToanTN
namespace SD.DataAccess
{
    public partial class Contact
    {
        private static ServiceDBDataContext Dc = new ServiceDBDataContext();

        /// <summary>
        /// Get list contact
        /// </summary>
        /// <param name="filter">Filter the state of contact. True is active, False is unactive</param>
        /// <param name="firstName">first name</param>
        /// <param name="surName">Surname</param>
        /// <param name="maximumRows">max record that we want to get</param>
        /// <param name="startRowIndex">start row index</param>
        /// /// <param name="sortType">sort type</param>
        /// <returns>A list contact</returns>
        public static List<Contact> GetListContact(bool filter = false, string firstName = null,
            string surName = null, int maximumRows = 10, int startRowIndex = 0, string sortType = null)
        {
            // author: ToanTN, version: 1.0, Date: 11 Dec 2012
            // Modified by ToanTN, date 13 Dec 2012. ToanTN added sort function and modified filter

            IQueryable<Contact> contacts = null;

            // 1. Filter
            if (filter) // get all contact
            {
                contacts = Dc.Contacts; // get all contact
            }
            else // just get actvie contact
            {
                contacts = Dc.Contacts.Where(c => c.IsActive == true);
            }
            if (firstName != null) // filter by first name
            {
                contacts = contacts.Where(c => c.FirstName.ToLower().Contains(firstName.ToLower()));
            }
            if (surName != null) // filter by sur name
            {
                contacts = contacts.Where(c => c.Surname.ToLower().Contains(surName.ToLower()));
            }

            //2. Sort data
            contacts = SortContacts(contacts, sortType);

            //3. get data from DB
            contacts = contacts.Skip(startRowIndex).Take(maximumRows);// get records from DB
            return contacts.ToList();
        }

        /// <summary>
        /// Sort data
        /// </summary>
        /// <param name="data">The data that we want to sort.</param>
        /// <param name="sortType">Type of the sort.</param>
        /// <returns></returns>
        private static IQueryable<Contact> SortContacts(IQueryable<Contact> data, string sortType)
        {
            // the sortType is a string with format: "XXX YYY"
            // "XXX" is the column name that we want to sort
            // "YYY" is ASC or DESC. Default value is ASC

            bool sortDescending = false;

            if (!string.IsNullOrEmpty(sortType))
            {
                var values = sortType.Split(' ');
                sortType = values[0];

                if (values.Length > 1)
                {
                    sortDescending = (values[1] == "DESC");
                }

                switch (sortType)
                {
                    case "FisrtName":
                        data = sortDescending
                                   ? data.OrderByDescending(c => c.FirstName)
                                   : data.OrderBy(c => c.FirstName);
                        break;

                    case "Surname":
                        data = sortDescending
                                   ? data.OrderByDescending(c => c.Surname)
                                   : data.OrderBy(c => c.Surname);
                        break;

                    case "MobilePhone":
                        data = sortDescending
                                   ? data.OrderByDescending(c => c.MobilePhone)
                                   : data.OrderBy(g => g.MobilePhone);
                        break;

                    case "Email":
                        data = sortDescending
                                   ? data.OrderByDescending(c => c.Email)
                                   : data.OrderBy(c => c.Email);
                        break;

                    case "ContactTypeName":
                        data = sortDescending
                                   ? data.OrderByDescending(c => c.ContactType.ContactTypeName)
                                   : data.OrderBy(c => c.ContactType.ContactTypeName);
                        break;

                    case "IsActive":
                        data = sortDescending
                                   ? data.OrderByDescending(c => c.IsActive)
                                   : data.OrderBy(c => c.IsActive);
                        break;
                    default:
                        data = sortDescending
                                   ? data.OrderByDescending(c => c.ContactId)
                                   : data.OrderBy(c => c.ContactId);
                        break;
                }
            }

            return data;
        }

        /// <summary>
        /// Count contacts. This method support paging gridview
        /// </summary>
        /// <param name="filter">Filter the state of contact. True is active, False is unactive</param>
        /// <param name="firstName">first name</param>
        /// <param name="surName">sur name</param>
        /// <returns></returns>
        public static int CountContacts(bool filter = false, string firstName = null, string surName = null)
        {
            // author: ToanTN, version: 1.0, Date: 11 Dec 2012
            IQueryable<Contact> contacts = null;
            // 1. Filter
            if (filter) // get all contact
            {
                contacts = Dc.Contacts; // get all contact
            }
            else // just get actvie contact
            {
                contacts = Dc.Contacts.Where(c => c.IsActive == true);
            }
            if (firstName != null)// filter by first name
            {
                contacts = contacts.Where(c => c.FirstName.ToLower().Contains(firstName.ToLower()));
            }
            if (surName != null)// filter by sur name
            {
                contacts = contacts.Where(c => c.Surname.ToLower().Contains(surName.ToLower()));
            }
            return contacts.ToList().Count;
        }


        /// <summary>
        /// Selects all contact types.
        /// </summary>
        /// <returns></returns>
        public static IQueryable<ContactType> SelectAllContactTypes()
        {
            // author: ThungNN, version: 1.0, Date: 11 Dec 2012
            IQueryable<ContactType> data = Dc.ContactTypes.Select(c => c);
            return data;
        }

        /// <summary>
        /// Selects all best method contact
        /// </summary>
        /// <returns></returns>
        public static IQueryable<BestContactMethod> SelectAllBestMethodContacts()
        {
            // author: ThungNN, version: 1.0, Date: 11 Dec 2012
            IQueryable<BestContactMethod> data = Dc.BestContactMethods.Select(c => c);
            return data;
        }

        /// <summary>
        /// Get contact by id
        /// </summary>
        /// <param name="contactId">contact id</param>
        /// <returns></returns>
        public static Contact GetContactById(int contactId)
        {
            // author: ToanTN, version: 1.0, Date: 11 Dec 2012            
            Contact contact = Dc.Contacts.SingleOrDefault(c => c.ContactId == contactId);
            return contact;
        }

        /// <summary>
        /// Insert contat into DB
        /// </summary>
        /// <param name="contact">contact to insert</param>
        public static void InsertContact(Contact contact)
        {
            // author: ToanTN, version: 1.0, Date: 11 Dec 2012            
            Dc.Contacts.InsertOnSubmit(contact); // insert contact
            Dc.SubmitChanges(); // save

        }


        /// <summary>
        /// Updates the contact.
        /// </summary>
        /// <param name="contact">The contact.</param>
        /// <returns></returns>
        public static bool UpdateContact(Contact contact)
        {
            // author: ToanTN, version: 1.0, Date: 11 Dec 2012            
            Contact currentContact = Dc.Contacts.FirstOrDefault(c => c.ContactId == contact.ContactId);
            if (currentContact != null)
            {
                // set value for contact to insert into DB
                currentContact.FirstName = contact.FirstName;
                currentContact.Surname = contact.Surname;
                currentContact.KnownAs = contact.KnownAs;
                currentContact.OfficePhone = contact.OfficePhone;
                currentContact.MobilePhone = contact.MobilePhone;
                currentContact.HomePhone = contact.HomePhone;
                currentContact.Email = contact.Email;
                currentContact.ManageId = contact.ManageId;
                currentContact.ContactTypeId = contact.ContactTypeId;
                currentContact.BestContactMethodId = contact.BestContactMethodId;
                currentContact.JobRole = contact.JobRole;
                currentContact.WorkBase = contact.WorkBase;
                currentContact.JobTitle = contact.JobTitle;
                currentContact.IsActive = contact.IsActive;
                Dc.SubmitChanges(); // save
                return true;
            }
            return false;
        }
        
        
        //---------------author: vidt----------
        public Contact FindContactById(int id)
        {
            var contact = Dc.Contacts.FirstOrDefault(c => c.ContactId == id);
            return contact;
        }
        /// <summary>
        /// Gets the list query.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="filter">The filter.</param>
        /// <returns>Contact list</returns>
        public static IQueryable<Contact> GetListQuery(IQueryable<Contact> data, ContactFilter filter)
        {
            // Filter by first name
            if (filter.FirstName != null)
            {
                data = data.Where(c => c.FirstName.StartsWith(filter.FirstName));
            }

            // Filter by Surname name
            if (filter.Surname != null)
            {
                data = data.Where(c => c.Surname.StartsWith(filter.Surname));
            }

            // Filter by in-active & active contact
            if (!filter.IncludeInactive)
            {
                data = data.Where(c => c.IsActive);
            }

            return data;
        }
        /// <summary>
        /// Gets the list sort.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="sortType">Type of the sort.</param>
        /// <returns></returns>
        private static IQueryable<Contact> GetListSort(IQueryable<Contact> data, string sortType)
        {
            var sortDescending = false;

            if (!string.IsNullOrEmpty(sortType))
            {
                var values = sortType.Split(' ');
                sortType = values[0];

                if (values.Length > 1)
                {
                    sortDescending = (values[1] == "DESC");
                }

                switch (sortType)
                {
                    case "ContactName":
                        data = sortDescending
                                   ? data.OrderByDescending(c => c.FirstName).ThenBy(c => c.Surname)
                                   : data.OrderBy(c => c.FirstName).ThenBy(c => c.Surname);
                        break;

                    case "MobilePhone":
                        data = sortDescending
                                   ? data.OrderByDescending(c => c.MobilePhone)
                                   : data.OrderBy(g => g.MobilePhone);
                        break;

                    case "Email":
                        data = sortDescending
                                   ? data.OrderByDescending(c => c.Email)
                                   : data.OrderBy(c => c.Email);
                        break;

                    case "ContactTypeName":
                        data = sortDescending
                                   ? data.OrderByDescending(c => c.ContactType.ContactTypeName)
                                   : data.OrderBy(c => c.ContactType.ContactTypeName);
                        break;

                    case "IsActive":
                        data = sortDescending
                                   ? data.OrderByDescending(c => c.IsActive)
                                   : data.OrderBy(c => c.IsActive);
                        break;
                    default:
                        data = sortDescending
                                   ? data.OrderByDescending(c => c.ContactId)
                                   : data.OrderBy(c => c.ContactId);
                        break;
                }
            }

            return data;
        }
        /// <summary>
        /// Gets the list count.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <returns>Number of list count</returns>
        public int GetListCount(ContactFilter filter)
        {
            var data = from c in Dc.Contacts
                       select c;
            return GetListQuery(data, filter).Count();
        }
        /// <summary>
        /// Gets the list.
        /// </summary>
        /// <param name="filter">The filter.</param>
        /// <param name="sortType">Type of the sort.</param>
        /// <param name="startRowIndex">Start index of the row.</param>
        /// <param name="max">The max.</param>
        /// <returns>Contact list query</returns>
        public IQueryable<Contact> GetList(ContactFilter filter, string sortType, int startRowIndex, int max)
        {
            var data = from c in Dc.Contacts
                       select c;

            // 1. Filter by condition
            if (filter != null)
            {
                data = GetListQuery(data, filter);
            }

            // 2. Sorting
            data = GetListSort(data, sortType);

            // 3. Limit the rows
            data = data.Skip(startRowIndex).Take(max);

            return data;
        }

        public IQueryable<Contact> GetListContact(ContactFilter filter, string sortType, int startRowIndex, int max)
        {
            char[] specialCharacters = { '~', '!', '@', '$', '^', '%', '&', '^', '*', '?', '<', '>', '[', ']', '{', '}', ':' };

            var data = from c in Dc.Contacts
                       select c;

            // 1. Filter by condition
            if (filter != null)
            {
                data = GetListQuery(data, filter);
            }

            // 2. Sorting
            data = GetListSort(data, sortType);

            // 3. Limit the rows
            data = data.Skip(startRowIndex).Take(max);

            return data;
        }
    }
}
